package org.bulldog.playlist.program;

import org.bulldog.playlist.PlayListBuilder;
import org.bulldog.playlist.util.DateUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 插播时间点重叠播表生成器
 *
 * @author zhanghongbin
 * @version 1.0
 */
final class SpotsOverlapPlayListBuilder implements PlayListBuilder<List<Program>, Program> {


    private List<Program>[] sportsDailyProgramArray;

    public SpotsOverlapPlayListBuilder(List<Program>[] sportsDailyProgramArray) {
        this.sportsDailyProgramArray = sportsDailyProgramArray;
    }

    private List<Program> merge(List<Program> programList) {
        List<Program> tempProgramList = new ArrayList<>();
        for (int i = 0; i < sportsDailyProgramArray.length; i++) {
            Program program = sportsDailyProgramArray[i].get(0);
            String startTime = program.getStartTime();
            String endTime = program.getEndTime();
            Program tempProgram = new Program();
            tempProgram.setStartTime(startTime);
            tempProgram.setEndTime(endTime);
            tempProgram.getParams().putAll(program.getParams());
            tempProgram.getParams().put("@@index", i);
            tempProgramList.add(tempProgram);
        }
        if (!programList.isEmpty()) {
            tempProgramList.addAll(programList);
            Collections.sort(tempProgramList, new ProgramAscendingOrder.TimeAscendingOrder());
        }
        return tempProgramList;
    }

    @Override
    public List<Program> build(List<Program> programs) {
        String currentTime = DateUtil.now();
        String currentDate = currentTime.split(" ")[0] + " ";
        List<Program> programList = this.merge(programs);
        for (int i = 0; i < programList.size(); i++) {
            Program program1 = programList.get(i);
            //如果开始时间小于结束时间需要移除
            if (this.compareTime(currentTime, currentDate + " " + program1.getEndTime()) < 0) {
                programList.remove(i);
                i = i - 1;
                continue;
            }
            if (i + 1 >= programList.size()) {
                continue;
            }
            Program program2 = programList.get(i + 1);
            int n = this.compareTime(currentDate + " " + program1.getStartTime(), currentDate + " " + program2.getStartTime());
            if (n < 0
                    && this.compareTime(currentDate + " " + program1.getEndTime(), currentDate + " " + program2.getEndTime()) < 0) {
                programList.remove(i);
                i = i - 1;
                continue;
            }
            int n1 = DateUtil.minus(currentDate + " " + program2.getStartTime(), currentDate + " " + program1.getEndTime());
            if (n1 > 0) {
                int value = DateUtil.minus(currentDate + " " + program2.getEndTime(), currentDate + " " + program1.getEndTime());
                if (value > 0) {
                    if (this.exclude(program1, program2)) {
                        programList.remove(i + 1);
                        i = i - 1;
                        continue;
                    }
                    if (value < DateUtil.MIN_PLAY_DURATION) {
                        program2.setPlayDuration(n1); // 重置播放时间为节目2结束时间和节目1结束时间的差值
                        program2.setEndTime(program1.getEndTime());
                    } else {
                        Program newProgram = new Program(program1.getId(), program1.getName(), program1.getUrl(), value);
                        Map<String, Object> params = newProgram.getParams();
                        params.putAll(program1.getParams());
                        newProgram.setLevel(program1.getLevel());
                        newProgram.setStartTime(program2.getEndTime());
                        newProgram.setEndTime(program1.getEndTime());
                        newProgram.setPlayDuration(value);
                        programList.add(newProgram);
                        Collections.sort(programList, new ProgramAscendingOrder.TimeAscendingOrder());
                    }
                }
                if (this.compareTime(currentTime, currentDate + " " + program2.getStartTime()) < 0) {
                    if (DateUtil.isBetween(currentDate + " " + program1.getEndTime(), currentDate + " " + program2.getStartTime(),
                            currentDate + " " + program2.getEndTime())) {
                        program2.setStartTime(program1.getEndTime());
                        program2.setPlayDuration(DateUtil.minus(program1.getEndTime(), program2.getEndTime()));
                        Collections.sort(programList, new ProgramAscendingOrder.TimeAscendingOrder());
                    } else {
                        programList.remove(i + 1);
                    }
                    i = i - 1;
                } else {
                    //双重判断必须加
                    if (n < 0) {
                        if (value < 0) {
                            program2.setStartTime(program1.getEndTime());
                            program2.setPlayDuration(DateUtil.minus(program1.getEndTime(), program2.getEndTime()));
                            Collections.sort(programList, new ProgramAscendingOrder.TimeAscendingOrder());
                        } else {
                            programList.remove(i);
                        }
                        i = i - 1;
                    } else {
                        if (this.exclude(program1, program2)) {
                            programList.remove(i + 1);
                            i = i - 1;
                            value = DateUtil.minus(program1.getEndTime(), program2.getEndTime());
                            Program newProgram = new Program(program2.getId(), program2.getName(), program2.getUrl(), value);
                            Map<String, Object> params = newProgram.getParams();
                            params.putAll(program2.getParams());
                            newProgram.setLevel(program2.getLevel());
                            newProgram.setStartTime(program1.getEndTime());
                            newProgram.setEndTime(program2.getEndTime());
                            newProgram.setPlayDuration(value);
                            programList.add(newProgram);
                            Collections.sort(programList, new ProgramAscendingOrder.TimeAscendingOrder());
                        } else {
                            program1.setPlayDuration(n);// 重置播放时间为节目1开始时间和节目2开始时间的差值
                            program1.setEndTime(program2.getStartTime());
                        }
                    }
                }
            }
        }
        return programList;
    }


    /**
     * 根据createTime 时间进行排除
     *
     * @param program1
     * @param program2
     * @return
     */
    private boolean exclude(Program program1, Program program2) {
        if (program1.getParams().containsKey("createTime")) {
            String createTime1 = program1.getParams().get("createTime").toString();
            String createTime2 = program2.getParams().get("createTime").toString();
            if (DateUtil.compare(createTime1, createTime2) == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param time1
     * @param time2
     * @return
     */
    private int compareTime(String time1, String time2) {
        int n = DateUtil.minus(time1, time2);
        if (n < DateUtil.MIN_PLAY_DURATION) {
            return -1;
        }
        return n;
    }

}
